package com.knowledge.plus.泛型.泛型方法;

/**
 * 示例：泛型方法
 * 只有在方法签名中声明了 <T> 的方法才是泛型方法，仅使用了泛型类定义的类型参数的方法并不是泛型方法。
 * <p>
 * 注：
 * 泛型类中定义的类型参数和泛型方法中定义的类型参数是相互独立的，它们一点关系都没有，泛型方法始终以自己声明的类型参数为准。
 * <p>
 * 泛型方法的使用：
 * 泛型类，在创建类的对象的时候确定类型参数的具体类型；
 * 泛型方法，在调用方法的时候再确定类型参数的具体类型。
 *
 * @author TPF
 * @since 2023/7/14
 */
public class GenericMethod<U> {

    /**
     * 普通方法：
     * 该方法只是使用了泛型类定义的类型参数，不是泛型方法！
     */
    public void testMethod(U u) {
        System.out.println(u);
    }

    /**
     * 泛型方法：
     * 当在一个方法签名中的返回值前面声明了一个 <T> 时，该方法就被声明为一个泛型方法
     * <T> 表明该方法声明了一个类型参数 T
     */
    public <T> T testMethod1(T t) {     // T 可以被其它类型替换，如 U；泛型类中定义的类型参数和泛型方法中定义的类型参数是相互独立的
        return t;
    }

    /**
     * 泛型方法中可以同时声明多个类型参数
     */
    public <T, S, V> T testMethod(T t, S s, V v) {
        // do something
        return t;
    }

    /**
     * 泛型方法中也可以使用泛型类中定义的泛型参数
     */
    public <T> U testMethod(T t, U u) {
        return u;
    }

    public static <T> GenericMethod<T> build() {
        GenericMethod genericMethod = new GenericMethod();
        // do something
        return genericMethod;
    }

}